#include "md5Model.h"


extern cModelBuilder* g_pModelBuilder;

/*
==================
cModelBuilder
==================
*/


cModelBuilder::cModelBuilder()
{
	vecModel.clear();
}

void cModelBuilder::OnInit()
{
	m_pShaderMgr = GetShaderMgr();
	m_pShaderMgr->PushShader( L"../../files/fxFiles/model.fx", "model" );

	m_pLuaMgr = GetLuaMgr();

	lua_State* pL = m_pLuaMgr->GetLuaState();

	lua_getglobal( pL, "ModelMgr" );
	string key,file;
	for( int i = 1; ; ++i )
	{
		cModel* pModel = new cModel;

		if( !CreateModel( pL, i, pModel ) ){
			SAFE_DELETE( pModel );
			break;
		}
	}
	lua_pop( pL, 1 );
}

void cModelBuilder::Render()
{
	for( int i = 0; i != vecModel.size(); ++i )
	{
		vecModel[ i ]->Render();
	}
}

void cModelBuilder::Update( float dt )
{
	lua_State* pL = m_pLuaMgr->GetLuaState();
	lua_getglobal( pL, "update" );
	lua_pushnumber( pL, dt );
	if( lua_pcall( pL, 1, 0, 0 ) != 0 ){
		ERRBOX( lua_tostring( pL, -1 ) );
	}

	LuaUpdate( pL );

	for( int i = 0; i != vecModel.size(); ++i )
	{
		vecModel[ i ]->Update( dt );
	}
}

bool cModelBuilder::CreateModel( lua_State* pL, int iModel, cModel* pModel )
{
	string key,file;

	lua_pushnumber( pL, iModel );
	lua_gettable( pL, -2 );

	if( lua_istable( pL, -1 ) == 0)
		return false;

	GetString( pL, "id", key );
	GetString( pL, "modelfile", file );

	D3DXVECTOR3 pos;
	GetVector( pL, "pos", pos );
	pModel->SetPos( pos );
	
	D3DXVECTOR3 dir;
	GetVector( pL, "dir", dir );
	pModel->SetDir( dir );

	float angle;
	GetNumber( pL, "angle", angle );
	pModel->SetAngle( angle );
	
	pModel->OnInit( file, key );
	vecModel.push_back( pModel );

	lua_pop( pL, 1 );
	return true;
}

void cModelBuilder::SetModelAnim( int iModel, string currAnim  )
{
	vecModel[ iModel ]->SetCurrAnim( currAnim );
}
void cModelBuilder::SetModelWorldMat( int iModel, D3DXMATRIX mat )
{
	vecModel[ iModel ]->SetWorldMatrix( mat );
}

void cModelBuilder::LuaUpdate( lua_State* pL )
{
	UpdateModel( pL );
}

void cModelBuilder::UpdateModel( lua_State* pL )
{
	lua_getglobal( pL, "ModelMgr" );
	lua_getfield( pL, -1, "size" );
	size_t size = lua_tointeger( pL, -1 );
	lua_pop( pL,1 );

	//update from lua
	for( int i = 1; i <= size ; ++i )
	{
		lua_pushnumber( pL, i );
		lua_gettable( pL, -2 );

		string anim;
		GetString( pL, "curranim", anim );
		vecModel[ i - 1 ]->SetCurrAnim( anim );
		
		D3DXVECTOR3 dir;
		GetVector( pL, "dir", dir );
		vecModel[ i - 1 ]->SetDir( dir );

		float angle;
		GetNumber( pL, "angle", angle );
		vecModel[ i - 1 ]->SetAngle( angle );
		
		lua_pop( pL, 1 );
	}
	lua_pop( pL, 1 );

	//update lua info
	SetLuaModelInfo( pL );
}

void cModelBuilder::Release()
{
	for( int i = 0; i != vecModel.size(); ++i )
	{
		vecModel[ i ]->Release();
		SAFE_DELETE( vecModel[ i ] );
	}
	vecModel.clear();
}

void cModelBuilder::SetLuaModelInfo( lua_State* pL )
{
	vector< cModel* > vecModel = g_pModelBuilder->GetVecModel();

	lua_getglobal( pL, "ModelMgr" );

	for( int i = 0; i != vecModel.size(); ++i )
	{
		lua_pushnumber( pL, i + 1 );
		lua_gettable( pL, -2 );

		SetVector( pL, "pos", vecModel[ i ]->GetPos() );

		lua_pop( pL, 1 );
	}
	lua_pop( pL, 1 );
	return ;
}
